home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / amber / amber.lha / Callstate.c < prev    next >
C/C++ Source or Header  |  1991-04-25  |  3KB  |  126 lines

  1. /*
  2.  * Callstate.c
  3.  *
  4.  * Machine dependent code to remember and restore the callstate
  5.  * so that we can "squirrel" away a user's function call and make it
  6.  * later.
  7.  *
  8.  */
  9.  
  10. #include <stream.h>
  11. #include "Defs.h"
  12. #include "Object.h"
  13. #include "Callstate.h"
  14. static char rcsid[] = "$Header: /var/a/oriole/u1/thekkath/amber/RCS/Callstate.c,v 1.1 90/08/22 16:54:31 thekkath Exp Locker: thekkath $";
  15. void Callstate::Init()
  16. {
  17.     cs_len = CS_MAXARGS;
  18.     cs_argvd = 0;
  19. }    
  20.  
  21.  
  22. extern void    bcopy(char*, char*, int);
  23.  
  24. Callstate::~Callstate()
  25. {
  26.     if (cs_argvd)
  27.         delete cs_argvd;
  28. }
  29.  
  30. //
  31. // Callstate set called with:
  32. //    pointer to function to be called later on
  33. //    number of args (longwords) it should get called with
  34. //    a pointer to the base of those args
  35. //
  36. // We store this information away and later shove it on to the call
  37. // stack of the function we want to call.
  38. //
  39.  
  40. //
  41. // Copy the arglist into the callstate.  
  42. //    If there are args,
  43. //        and the # args > size of cs space, then
  44. //                delete the existing dynamic cs space
  45. //                make some new ones
  46. //                record size of new cs space
  47. //                copy args into new dynamic space
  48. //        else, have enough room somewhere.  Copy args
  49. //        into dynamic space (if we have it), else into
  50. //        static area.
  51. //
  52. // comments in Callstate::Call below.
  53. //
  54. void
  55. Callstate::Set(Objany boundObj, PFany f, int argc, int *argv)
  56. {
  57.     register int *ap;
  58.  
  59.         cs_bound = boundObj;
  60.     cs_func = (PFIany)f;
  61.     cs_argc = argc;
  62.     if (argc)    {
  63.         if (argc > cs_len)    {
  64.             delete cs_argvd;
  65.             ap = cs_argvd = new int [argc];
  66.             cs_len = cs_argc;
  67.         } else {
  68.             ap = (cs_argvd) ? cs_argvd : cs_argvs;
  69.         }
  70.         bcopy((char*)argv, (char*)ap, argc * sizeof(int));
  71.     }
  72. }
  73.  
  74.  
  75. //
  76. // Perform the actual call.
  77. // XXX MACHDEP
  78. //
  79. Objany
  80. Callstate::Call()
  81. {
  82.     int func = (int)cs_func;
  83.     int stackbytes = cs_argc * sizeof(long);
  84.     int *ap; 
  85.         int mipscall(Objany,PFIany,int,int *);
  86.  
  87.  
  88.         // On the mips the first 4 args go in registers the next on
  89.         // the stack. The situ is more complicated if one of the args
  90.         // is a float.
  91.         //
  92.  
  93.         if (cs_argvd) {
  94.         ap = cs_argvd;
  95.         } else {
  96.         ap = cs_argvs;
  97.         }
  98.         switch(cs_argc) {
  99.         case 0:
  100.                 return (Objany) (*cs_func)(cs_bound);
  101.         case 1:
  102.                 return (Objany) (*cs_func)(cs_bound,ap[0]);
  103.         case 2:
  104.                 return (Objany) (*cs_func)(cs_bound,ap[0],ap[1]);
  105.         case 3:
  106.                 return (Objany) (*cs_func)(cs_bound,ap[0],ap[1],ap[2]);
  107.         default:
  108.                 return (Objany) mipscall(cs_bound,cs_func,cs_argc,ap);
  109.         }
  110. }
  111.  
  112.  
  113. void
  114. Callstate::Print(ostream& s)
  115. {
  116.     s << form("(Callstate)this=0x%x, cs_func=0x%x, cs_argc=0x%x, cs_argvs=0x%x, cs_argvd=0x%x", 
  117.         this, cs_func, cs_argc, cs_argvs, cs_argvd);
  118. }
  119.  
  120.  
  121. ostream& operator<<(ostream& s, Callstate& c)
  122. {
  123.     c.Print(s);
  124.     return s;
  125. }
  126.